package Matdiscalc;
/**
 *
 * @author Iqbal, Reza, Mufid
 */
public class MatrixChecker {

    private int[][] matrix;
    public int counterMax = 0;
    public int counterMin = 0;
    public boolean poset = false;
    public boolean setara = false;
    String lookUp = "abcdefghij";
    /**
     * constructor class MatrixChecker
     * inputnya adalah matrix int 2 dimensi
     * @param m 
     */
    public MatrixChecker(int[][] m) {
        this.matrix = m;
    }
    /**
     * mencetak relasi dari matrix
     * @return string dari relasi matrix
     */
    public String cetak() {
        return cetakRelasi(matrix);
    }
    /**
     * cek kerefleksifan matrix
     * @return boolean sifat refleksif true/false
     */
    public boolean isRefleksif() {
        boolean cek = true;
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[i][i] == 0) {
                cek = false;
                return cek;
            }
        }
        return cek;
    }
    /**
     * cek keirrefleksifan matrix
     * @return boolean sifat irrefleksif true/false
     */
    public boolean isIrrefleksif() {
        boolean cek = true;
        for (int i = 0; i < matrix.length; i++) {
            if (matrix[i][i] == 1) {
                cek = false;
                return cek;
            }
        }
        return cek;
    }
    /**
     * cek simetri matrix
     * @return boolean sifat simetri true/false
     */
    public boolean isSimetri() {
        boolean cek = true;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                if (matrix[i][j] != matrix[j][i]) {
                    cek = false;
                    return cek;
                }
            }
        }
        return cek;
    }
    /**
     * cek antisimetri matrix
     * @return boolean sifat antisimetri true/false
     */
    public boolean isAntiSimetri() {
        boolean cek = true;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                if (i != j && (matrix[i][j] == matrix[j][i] )) {
                    cek = false;
                    return cek;
                }
            }
        }
        return cek;
    }
    /**
     * cek asimetri matrix
     * @return boolean sifat asimetri true/false
     */
    public boolean isAsimetri() {
        boolean cek = true;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++) {
                if (matrix[i][j] == matrix[j][i] ) {
                    cek = false;
                    return cek;
                }
            }
        }
        return cek;
    }
    /**
     * cek transitif matrix
     * @return boolean sifat transitif true/false
     */
    public boolean isTransitif() {
        boolean cek = true;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                for (int k = 0; k < matrix.length; k++) {
                    if (matrix[i][j] == 1 && matrix[j][k] == 1 && matrix[i][k] == 0) {
                        cek = false;
                        return cek;
                    }
                }
            }
        }
        return cek;
    }
    /**
     *memberikan penutup refleksif matrix
     * @return string relasi penutup refleksif
     */
    public String penutupRefleksif(){
        int [][] m = copyMatrix(matrix);
        for (int i = 0; i < m.length; i++) {
            m[i][i] = 1;
        }
        //System.out.println("Relasi Masukan: "+cetak());
        return cetakRelasi(m);
    }
    /**
     *memberikan penutup simetri matrix
     * @return string relasi penutup simetri
     */
    public String penutupSimetri(){
        int [][] m = copyMatrix(matrix);
        for (int i = 0; i < m.length; i++) {
            for (int j = 0; j < m.length; j++) {
                if (m[i][j] != m[j][i]) {
                    m[i][j] = 1;
                    m[j][i] = 1;
                }
            }
        }
        //System.out.println("Relasi Masukan: "+cetak());
        return cetakRelasi(m);
    }
    /**
     *memberikan penutup transitif matrix
     * @return string relasi penutup transitif
     */
    public String penutupTransitif(){
        int [][] m = copyMatrix(matrix);
        for (int i = 0; i < m.length; i++) {
            for (int j = 0; j < m.length; j++) {
                for (int k = 0; k < m.length; k++) {
                    if (m[i][j] == 1 && m[j][k] == 1) {
                        m[i][k] = 1;
                    }
                }
            }
        }
        //System.out.println("Relasi Masukan: "+cetak());
        return cetakRelasi(m);
    }
    /**
     * cetak relasi dari matrix masukan
     * @param m
     * @return string relasi dari matrix
     */
    private String cetakRelasi(int[][] m){
        String result = "";
        for(int i = 0; i < m.length; i++){
            for(int j = 0; j< m.length; j++){
                if(m[i][j] == 1){
                    result += "("+lookUp.charAt(i)+","+lookUp.charAt(j)+") ";   
                }
            }
        }
        return result;
    }
    /**
     * mencopy isi matrix
     * @param mat
     * @return matrix masukan
     */
    private int[][] copyMatrix(int [][] mat){
        int[][] m = new int [mat.length][mat.length];
        for(int i = 0; i < mat.length; i++){
            System.arraycopy(mat[i], 0, m[i], 0, mat.length);
        }
        return m;
    }
    /**
     * mengecek sifat setara matrix relasi
     * @return boolean sifat setara relasi
     */
    public boolean isSetara(){
        boolean isSimetri = false, isRefleksif = false, isTransitif = false;
        if(isSimetri()==true){
            isSimetri = true;
        }
        if(isRefleksif()==true){
            isRefleksif = true;
        }
        if(isTransitif()==true){
            isTransitif = true;
        }
        if(isSimetri==true && isRefleksif==true && isTransitif==true){
            setara=true;
        }
        if(setara == true){
            findPartition();
        }
        else System.out.println("Matrix tidak setara");
        return setara;
    }
    /**
     * menemukan partisi dari matrix setara
     * @return string huimpunan relasi setara
     */
    public String findPartition(){
        String var = "";
        boolean cek= true;
        int [][] m = matrix;
        boolean[] stop = new boolean[m.length];
        for (int i = 0; i < matrix.length; i++) { 
            var+="{";
            for (int j = 0; j < matrix[i].length; j++) {    
                if(matrix[i][j] == 1 && !stop[j]){
                    stop[j]= true;
                    var += lookUp.charAt(j)+",";
                    cek=false;
                }        
           }
            var= var.substring(0, var.length()-1);
            if(cek==false){var+= "}";}
            cek=true;
        }
            return var;
    }
    /**
     * mengecek sifat poset
     * jika poset akan mencari elemen terbesar, terkecil, maksimum dan minimum
     * @return boolean sifat poset matrix
     */
    public boolean isPoset(){
        boolean isAntiSimetri = false, isRefleksif = false, isTransitif = false;
        if(isAntiSimetri()==true){
            isAntiSimetri = true;
        }
        if(isRefleksif()==true){
            isRefleksif = true;
        }
        if(isTransitif()==true){
            isTransitif = true;
        }
        if(isAntiSimetri==true && isRefleksif==true && isTransitif==true){
            poset=true;
        }
        if(poset == true){
            findMaxElement();
            findMinElement();
        }
        else System.out.println("Matrix tidak poset");
        return poset;
    }
    /**
     * menemukan elemen maksimum dari relasi jika poset
     * @return string elemen maksimum
     */
    public String findMaxElement(){
        String var = "";
        String result="";
        int [][] m = matrix;
        int [] counter = new int[m.length];
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if(matrix[i][j] == 1){
                    counter[i] = counter[i]+1;
                }
            }
        }
        for (int k = 0; k < counter.length; k++){
            if(counter[k]==1){
                var += lookUp.charAt(k)+" ";
                counterMax = counterMax+1;
            }
        }
        if(counterMax == 1){
            result = "Nilai terbesar adalah "+var;
        }
        else if(counterMax > 1){
            result = "Tidak ada nilai terbesar";
        }
        return result;
    }
    /**
     * menemukan elemen minimum dari relasi jika poset
     * @return string elemen minimum
     */
    public String findMinElement(){
        String var = "";
        String result="";
        int [][] m = matrix;
        int [] counter = new int[m.length];
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if(matrix[i][j] == 1){
                    counter[j] = counter[j]+1;
                }
            }
        }
        for (int k = 0; k < counter.length; k++){
            if(counter[k]==1){
                var += lookUp.charAt(k)+" ";
                counterMin = counterMin + 1;
            }
        }
        if(counterMin == 1){
            result = "Nilai terkecil adalah "+var;
        }
        else if(counterMin > 1){
            result = "Tidak ada nilai terkecil";
        }
        return result;
    }
}
